package demo3;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.PriorityQueue;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Hua YY
 * Date: 2024-08-17
 * Time: 13:55
 */








//无返回值无参数
@FunctionalInterface
interface NoParameterNoReturn {
    //注意：只能有一个方法
    void test();
    //void test2();//函数式接口只能有一个抽象方法，两个及两个以上会检测到报错
}

//无返回值一个参数
@FunctionalInterface
interface OneParameterNoReturn {
    void test(int a);
}

//无返回值多个参数
@FunctionalInterface
interface MoreParameterNoReturn {
    void test(int a,int b);
}


//有返回值无参数
interface NoParameterReturn{
    int test();
}


//有返回值一个参数
@FunctionalInterface
interface OneParameterReturn {
    int test(int a);
}



//有返回值多参数
@FunctionalInterface
interface MoreParameterReturn {
    int test(int a,int b);
}

//lambda缺点：不太好看，比较吃熟悉度，可读性差，不方便进行调试
public class Test {


    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<>();
        map.put(1, "hello");
        map.put(2, "bit");
        map.put(3, "hello");
        map.put(4, "lambda");
        map.forEach(new BiConsumer<Integer, String>() {
            @Override
            public void accept(Integer integer, String s) {
                System.out.println("key:" + integer + "value:" + s);
            }
        });
        map.forEach((key,v)-> System.out.println("key:" + key + "value:" + v));//两个参数的
    }





    public static void main8(String[] args) {
    ArrayList<String> list = new  ArrayList<>();
    list.add("lambda");
    list.add("Hello");
    list.add("bit");
    list.add("hello");

    list.forEach(new Consumer<String>() {
        //第一步
        @Override
        public void accept(String s) {
            System.out.println(s);//打印结果依次是上面的字符串
        }
    });

    System.out.println("=====简写后打印结果：=====");

    //第二步：简写
    list.forEach(s -> System.out.println(s));//lambda表达式你就可以理解成一个匿名内部类的实现


    System.out.println("=======   排序后：   ========");
    //第三步：sort方法排序的时候要告诉jvm怎么比较
    list.sort(new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o1.compareTo(o2);
        }
    });
    list.forEach(s -> System.out.println(s));


        System.out.println("简写");
    //第四步：用lambda表达式,两个参数，有返回
    list.sort((o1,o2)-> {return o1.compareTo(o2);});
    list.forEach(s-> System.out.println(s));


}





    public static void main7(String[] args) {
        MoreParameterReturn moreParameterReturn = (a,b)->a+b;
        MoreParameterReturn moreParameterReturn2 = (a,b)->{return a+b; };//有return才带{}
        System.out.println(moreParameterReturn2.test(4, 7));

    }

    public static void main6(String[] args) {
        //有返回值一个参数
        OneParameterReturn oneParameterReturn = a->{return a + 65;};//有返回值的必须要带花括号{}
        System.out.println(oneParameterReturn.test(1));

    }

    public static void main5(String[] args) {
        /*第一种常规写法
        * 不带参数，有返回值，直接带一个花括号返回就行
        * 再调用方法,去打印*/
        NoParameterReturn noParameterReturn1 = () -> {return 66;};
       System.out.println(noParameterReturn1.test());

       /*第二种写法
       *直接在lambda表达式后面接要返回的值
       * */
        NoParameterReturn noParameterReturn =() -> 10;
        //System.out.println(noParameterReturn);//不调用方法是打印不出来的哈
        System.out.println(noParameterReturn.test());
    }

    public static void main4(String[] args) {
        //无返回值多个参数
        MoreParameterNoReturn moreParameterNoReturn = (a,b)-> System.out.println(a + b);
        moreParameterNoReturn.test(10,4);
    }



    public static void main3(String[] args) {
        //无返回值一个参数
        OneParameterNoReturn oneParameterNoReturn = (int a)->{ //一个参数的话前面写不写int类型和()带不带好像都一样,即多个参数下可以省略参数类型
            System.out.println("oneParameterNoReturn(牛13):"+a);
        };
        oneParameterNoReturn.test(666);
        //想写出这样的代码，就要了解接口中的方法

    }



    public static void main2(String[] args) {

    }




    public static void main1(String[] args) {
        int a = 6;
        //a = 12;lambda表达式同样是一样的，这就是变量捕获

        /*
        * 可以简写*/
        //无返回值无参数
        //简写lambda表达式                     不带参数的方法，
        NoParameterNoReturn noParameterNoReturn1 = ()-> System.out.println("重写了test方法" + a);
        noParameterNoReturn1.test();

        //===================================================//


        //                                     匿名内部类
        NoParameterNoReturn noParameterNoReturn = new NoParameterNoReturn() {

            @Override
            public void test() {
                //a = 66;  //匿名内部类中要么是常量，要么是没有修改过的变量
                System.out.println("重写了test方法"+a);/*匿名内部类实现内部类接口重写方法*/
            }
        };
        noParameterNoReturn.test();//调用test方法




        //==============================================================//




        PriorityQueue<Integer> minHeap = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return 0;
            }
        });
        //                                带一个new的对象的，写起来很麻烦，注意细节，花括号里面的;和括号外的;
        PriorityQueue<Integer> minHeap2 = new PriorityQueue<>( (o1,o2)-> {return o1-o2;} );//带有两个参数的lambda表达式
    }

}
